home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX503 / SECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  24.8 KB  |  1,037 lines

  1. /* sect.c */
  2.  
  3. /* 
  4.  * Aug-23-88 jye. Change and add codes so that can be used for MS-DOS
  5.  * Dec-20-89 jye. Free a bug that HDX gives a error message when CD-ROM 
  6.  *                  is busy. 
  7.  * Feb-11-93 jye. changed the size of the 'sentdate' buff to 56 bytes 
  8.  *                  for the 'inquiry', this will fit some hard drives. (Ex.
  9.  *                  IBM OME 0663E15)
  10.  */
  11.  
  12. #include "obdefs.h"
  13. #include "osbind.h"
  14. #include "mydefs.h"
  15. #include "part.h"
  16. #include "hdx.h"
  17. #include "addr.h"
  18. #include "myerror.h"
  19.  
  20. #define    ZBUFSIZ    0x4000        /* about 16k == 32 sectors */
  21. #define    ZCOUNT    (ZBUFSIZ/0x200)    /* ZCOUNT = 32 */
  22. #define MAXUNITS 16            /* max number of logical units */
  23.  
  24. #define PUNINFO struct _punifno
  25. PUNINFO {
  26.         WORD puns;    /* number of physical units */
  27.         BYTE pun[MAXUNITS];
  28.         LONG partition_start[MAXUNITS]; /* offset to partition on */
  29.                                         /* physical unit */
  30. };
  31. extern long ostack;        /* old stack pointer */
  32. extern UWORD errcode();        /* function to return error code */
  33. extern int yesscan;        /* the flag for the func. IBMGPART use */
  34. extern long sptrk;        /* the sector per track */
  35. extern int npart;        /* the number of partitions */
  36. extern int ext;            /* the index of extended partition */
  37. extern int extend;        /* the index of end extended partition */
  38. extern int showmany;    /* the flag for show the too many device alert box */
  39. extern char ttscsi;        /* the flag for SCSI if set */
  40. extern char spscsixst;    /* set for the sparrow scsi exist */
  41. extern int needscan;    /* TRUE: if it is the first time to scan the units */
  42. extern int athead;        /* the # of data heads on the AT drive */
  43. extern int atcyl;        /* the # of cylinders on the AT drive */
  44. extern int atspt;        /* the # of sectors per track on the AT drive */
  45. extern int noacsi;        /* set for no ACSI drive in the system */
  46. extern char slwacsi;    /* 1: set for slow acsi device */
  47. extern char *drvid[];    /* for the id of the devices */
  48. /*
  49.  * Logical-to-dev+partition mapping table.
  50.  */
  51. int nlogdevs;                /* # logical devices */
  52. LOGMAP logmap[EXTRALOGD];    /* logical dev map */
  53. int livedevs[MAXPHYSDEVS];    /* live devs flags; 1: device is alive */
  54. int idevs[16];                /* the devs have id flags; 1: device has id */
  55. int typedev = 0x0000;        /* if set, driver is a removable driver */
  56. int typedrv = 0x0000;        /* if set, driver is a SCSI driver */
  57. int atexst;                    /* AT drive exists */
  58. int slvexst;                /* AT slave drive exists */
  59. char useblit;                /* set for it is not the stbook drive */
  60. int floptical=0;            /* set if it a floptical drive */
  61.  
  62.  
  63. /*
  64.  * Rebuild logical-to-physical mapping
  65.  * by reading and interpreting the root
  66.  * blocks for all physical devs.
  67.  *
  68.  */
  69.  
  70. rescan(flag, fnp)
  71.  
  72. int flag;    /* 0: don't report medium change error; */
  73.             /* non-0: report medium change error; */
  74. int fnp;    /* 0: do zero & markbad; 1: do format & ship; 2: do part */
  75.  
  76. {
  77.     int dev, scan=0;
  78.     char buf[512];
  79.     char sendata[56];
  80.     int partno, ret, inqret, i;
  81.     PART *partinfo;
  82.     char mask = 0x80;    /* 7th bit is set on */
  83.     int setmask;
  84.     int maxloop;
  85.  
  86.     noacsi = 1;                /* assume there is no ACSI in the system */
  87.     ostack = Super(NULL);    /* set supervice mode */
  88.  
  89.     ttscsi = chkscsi();        /* check if SCSI exists */
  90.     spscsixst = chksp();    /* check if sparrow scsi exists */
  91.     delay();
  92.     if ((atexst = chkide()))    { /* AT drive exist */
  93.         if (stbook())    {
  94.             useblit = 0;
  95.         } else {
  96.             useblit = chkblit();
  97.         }
  98.         if ((ret = identify(16, buf)) == OK)    {
  99.             delay();
  100.             /* in byte 54 of the buf having the drive's id */
  101.             gdrvid(16, &buf[54], drvid[16]);
  102.             /* return the number of cylinder, head, spt */
  103.             gparmfc(&atcyl, &athead, &atspt, buf);
  104.         } else { 
  105.             delay();
  106.             Super(ostack);
  107.             ret = errcode(16);
  108.             if (tsterr(ret) != OK) 
  109.                 return ERROR;
  110.             return (-3);    /* don't have to show the alert box */
  111.         }
  112.     }
  113.     delay();
  114.     /*    Now the hardware doesn't support the slave drive, so comment it out
  115.     if ((atexst) && (slvexst = slave()))    {  AT slave drive exist 
  116.         if ((ret = identify(17, buf)) == OK)    {
  117.             atscyl = getword(buf+2);
  118.             atshead = getword(buf+6);
  119.             atsspt = getword(buf+12);
  120.             delay();
  121.         } else { 
  122.             delay();
  123.             Super(ostack);
  124.             ret = errcode(17);
  125.             if (tsterr(ret) != OK) 
  126.                 return ERROR;
  127.             return (-3);    don't have to show the alert box
  128.         }
  129.     }
  130.     */
  131.     delay();
  132.     Super(ostack);
  133.     /* set the scent message box */
  134.     if ((needscan) && ((ttscsi)||(spscsixst)))
  135.         dsplymsg(scanmsg);
  136.  
  137.     /* disable all logical and physical devs */
  138.     for (dev = 0; dev < EXTRALOGD; ++dev)
  139.         logmap[dev].lm_physdev = -1;
  140.  
  141.     for (dev = 0; dev < MAXPHYSDEVS; ++dev)
  142.         livedevs[dev] = 0;
  143.  
  144.     /* set all devices have no id */
  145.     for(i=0; i < 16; i++)    {
  146.         idevs[i] = 0;
  147.     }
  148.  
  149.     /*
  150.      * Scan all physical devs
  151.      * and pick up partition structures.
  152.      */
  153.     nlogdevs = 0;
  154.     showmany = 0;
  155.     slwacsi = 0;
  156.     if (atexst)    {
  157.         maxloop = 18;
  158.         dev = 16;
  159.     } else if ((ttscsi)||(spscsixst))    {
  160.         if (spscsixst)    {
  161.             slwacsi = 1;
  162.         } 
  163.         maxloop = 16;
  164.         dev = 8;
  165.     } else {
  166.         maxloop = 8;
  167.         slwacsi = 1;
  168.         dev = 0;
  169.     }
  170. rerescan:
  171.     for (; dev < maxloop; ++dev)
  172.     {
  173.  
  174.         if (((dev == 16) && atexst) || ((dev == 17) && slvexst))    {
  175.             if ((ret = getroot(dev, buf, (SECTOR)0)) != 0)    {
  176.                 if (tsterr(ret) != OK)    
  177.                     err(rootread);
  178.                 slwacsi = 0;
  179.                 return(ERROR);
  180.             }
  181.             goto atst;    /* skip and do the at stuff only */
  182.         }
  183.         /* initialize the buffer */
  184.         for (i = 0; i < 56; i++)        {
  185.             sendata[i] = 0;
  186.         }
  187.  
  188.         /* check see the drive is a what kind of drive */
  189.            ostack = Super(NULL);
  190.            delay();
  191.         if ((inqret = inquiry(dev, (WORD)56, sendata)) != ERROR)    {
  192.             for (i=8; i < 56; i++)    {
  193.                 if (sendata[i])    {
  194.                     break;
  195.                 }
  196.             }
  197.             if (i < 56)    {    /* there are some date return */
  198.                 if ((sendata[8] == 'I') &&    (sendata[9] == 'N') &&
  199.                     (sendata[10] == 'S') &&    (sendata[11] == 'I') &&
  200.                     (sendata[12] == 'T') &&    (sendata[13] == 'E') &&
  201.                     (sendata[16] == 'I') &&    (sendata[17] == '3') &&
  202.                     (sendata[18] == '2') &&    (sendata[19] == '5'))    {
  203.                     /* it is a floptical INSITE I325 drive */
  204.                     floptical = 1;
  205.                 }
  206.                 gdrvid(dev, &sendata[8], drvid[dev]);
  207.                 idevs[dev] = 1;
  208.             }
  209.         }
  210.            delay();
  211.            Super(ostack);
  212.         setmask = 0x0001;
  213.         if (inqret & 0x08)    { /* the device is busy */
  214.             continue;
  215.         }
  216.         /* ret not equal OK, it may be a regular hard drive */
  217.         if ((inqret == OK)||(inqret == 7)) { /*it is not a regular hard drive*/
  218.             if (sendata[0])      {    /* it is not a hard drive */
  219.                 continue;
  220.             } else if (sendata[1] & mask)    { /* it is a removable drive */
  221.                 if (spscsixst)    {
  222.                       /* it is a SCSI drive */
  223.                     /* set the relative bit, 1 is a SCSI, other is not */
  224.                     typedrv |= setmask << dev;
  225.                     /* set the relative bit, 1 is a removable */
  226.                     typedev |= setmask << dev;
  227.                 } else {
  228.                     ;            /* don't set the SCSI bit */
  229.                 }
  230.             } else if (dev > 7)    {
  231.                   /* it is a SCSI drive */
  232.                 /* set the relative bit, 1 is a SCSI, other is not */
  233.                 typedrv |= setmask << dev;
  234.             }
  235.         }
  236.         if ((ret = getroot(dev, buf, (SECTOR)0)) < 0) {
  237.             if (!fnp)  rangelog(dev);
  238.             continue;
  239.         } else {        /* ret >= 0 */
  240.             if (ret > 0) {
  241.                 if ((flag) && (tsterr(ret) == OK))    {    
  242.                 /* if non-0, report error if medium changed */
  243.                         erasemsg();
  244.                         slwacsi = 0;
  245.                          return ERROR;
  246.                 }
  247.                 if ((ret = getroot(dev, buf, (SECTOR)0))) {    /* try again */
  248.                     if (ret > 0 && flag && tsterr(ret) == OK)    {
  249.                         erasemsg();
  250.                         slwacsi = 0;
  251.                         return ERROR;
  252.                     } else if ((ret > 0) && (!flag))    {
  253.                         if (((inqret == OK)||(inqret == 7)) && 
  254.                                              (sendata[1] & mask))    { 
  255.                             /* it is a removable drive */
  256.                             /* but forget insert the cartridge */
  257.                             err(instdrv);
  258.                             /*
  259.                             erasemsg();
  260.                             */
  261.                             /* set the relative bit, 1 is a removable */
  262.                             typedev |= setmask << dev;
  263.                         }
  264.                         /*
  265.                         if (fnp == 1)    {  do format 
  266.                             livedevs[dev] = 1;
  267.                             if (dev < 8)  there is a ACSI in the system 
  268.                                 noacsi = 0;
  269.                             yesscan = 1;
  270.                         }
  271.                         */
  272.                     }
  273.                     if (!fnp)    {
  274.                         rangelog(dev);
  275.                     }
  276.                     continue;
  277.                 }
  278.             }
  279.             if ((inqret == OK)||(inqret == 7))     {  /* it is a SCSI drive */
  280.                 if (sendata[1] & mask)    { /* it is a removable drive */
  281.                     /* set the relative bit, 1 is a removable, other is not */
  282.                     typedev |= setmask << dev;
  283.                 }
  284.             }
  285.     atst:
  286.             if (dev < 8)    {    /* there is a ACSI drive in the system */
  287.                 noacsi = 0;
  288.             }
  289.             livedevs[dev] = 1;
  290.             yesscan = 1;
  291.             if (stgpart(dev, buf, (PART *)&partinfo) == ERROR)    {
  292.                 erasemsg();
  293.                 slwacsi = 0;
  294.                 return ERROR;
  295.             }
  296.             if (ext != NO_EXT)    {
  297.                 sortpart(partinfo,SCAN_BS); 
  298.             }
  299.         for (partno = 0; partno < npart; ++partno) {
  300.             if ((partinfo[partno].p_flg & P_EXISTS) &&
  301.                 (partinfo[partno].p_siz != (SECTOR)0) &&
  302.                 (((partinfo[partno].p_id[0] == 'G') &&
  303.                  (partinfo[partno].p_id[1] == 'E') &&
  304.                  (partinfo[partno].p_id[2] == 'M'))   ||
  305.                  ((partinfo[partno].p_id[0] == 'B') &&
  306.                  (partinfo[partno].p_id[1] == 'G') &&
  307.                  (partinfo[partno].p_id[2] == 'M'))))   
  308.             {
  309.                 if (nlogdevs > EXTRALOGD)    {
  310.                     continue;
  311.                 }
  312.                 logmap[nlogdevs].lm_physdev = dev;
  313.                 logmap[nlogdevs].lm_partno = partno;
  314.                 logmap[nlogdevs].lm_start =  partinfo[partno].p_st;
  315.                 logmap[nlogdevs].lm_siz =      partinfo[partno].p_siz;
  316.                 ++nlogdevs;
  317.                 if (nlogdevs == MAXLOGDEVS)         {
  318.                     showmany = 1;
  319.                 }
  320.             }
  321.         }
  322.     }
  323.     inipart(partinfo, npart);
  324.     if (partinfo > 0)    Mfree(partinfo);
  325.     }
  326.  
  327.     if ((maxloop > 16) && ((ttscsi)||(spscsixst)))    {
  328.         maxloop = 16;
  329.         dev = 8;
  330.         slwacsi = 0;
  331.         if (spscsixst)    {
  332.             slwacsi = 1;
  333.         }
  334.         goto rerescan;
  335.     } else if (((maxloop > 16) && ((!ttscsi)&&(!spscsixst))) 
  336.                                || ((ttscsi)&&(maxloop>8)))    {
  337.         maxloop = 8;
  338.         dev = 0;
  339.         slwacsi = 1;
  340.         goto rerescan;
  341.     }
  342.     erasemsg();
  343.     slwacsi = 0;
  344.     return OK;
  345. }
  346.  
  347.  
  348.  
  349. /* get the indentification of drive */
  350.  
  351. gdrvid(indx, sptr, dptr)
  352. int indx;
  353. char *sptr;
  354. char *dptr;
  355. {
  356.  
  357.     int i, j=0;
  358.  
  359.     /* string in ptr is sperated by space */
  360.     for (i=0; i < 24; i++)    {
  361.         if ((*dptr++ = *sptr++) == 0x20)    {
  362.             j++;
  363.             if (j > 1)    {
  364.                 dptr--;
  365.             }
  366.         } else {
  367.             j = 0;
  368.         }
  369.     }
  370.     *(dptr-1) = 0;
  371.     /*
  372.     while ((*sptr != 0x20) && (*sptr))    {
  373.         *dptr++ = *sptr++;
  374.     }
  375.     *dptr++ = 0x20;
  376.     sptr = ptr+8;
  377.     while ((*sptr != 0x20) && (*sptr))    {
  378.         *dptr++ = *sptr++;
  379.     }
  380.     *dptr = 0;
  381.     */
  382. }
  383.  
  384.  
  385. /* rerange the partition informations. */
  386.  
  387.  sortpart(pinfo, type)
  388.  PART *pinfo;
  389.  int type;                /* USER_ED = 1: for user interface use */
  390.                          /* SCAN_BS = 0: for rescan() and laybs() use */
  391.  {
  392.      int i, j, k;
  393.     PART rpart[2];
  394.  
  395.     if (ext == NO_EXT) return OK;    /* don't need sort */
  396.     for (i = 0; i < 2; i++)    { /* initialize the temple space */
  397.         rpart[i].p_flg = 0L;
  398.         rpart[i].p_st = 0L;
  399.         rpart[i].p_siz = 0L;
  400.         for (k = 0; k < 3; k++)
  401.             rpart[i].p_id[k] = '0';
  402.     }
  403.     /* save the partitions that after the extened partitions */
  404.     for (i = ext+1, j=0; i < 4; i++, j++)        {
  405.         if (pinfo[i].p_flg & P_EXISTS)    {
  406.             rpart[j].p_flg = P_EXISTS;
  407.             rpart[j].p_st = pinfo[i].p_st;
  408.             rpart[j].p_siz = pinfo[i].p_siz;
  409.             for (k = 0; k < 3; k++)
  410.                 rpart[j].p_id[k] = pinfo[i].p_id[k];
  411.         } 
  412.     }
  413.     /* move the extened partition to the front */
  414.      for (i=4, j = ext; i < npart; i++, j++)    {
  415.         if (pinfo[i].p_flg & P_EXISTS)    {
  416.             pinfo[j].p_flg = P_EXISTS;
  417.             pinfo[j].p_st = (type)?(pinfo[i].p_st):(pinfo[i].p_st + ROOTSECT);
  418.             pinfo[j].p_siz = (type)?(pinfo[i].p_siz):(pinfo[i].p_siz-ROOTSECT);
  419.             for (k = 0; k < 3; k++)
  420.                 pinfo[j].p_id[k] = pinfo[i].p_id[k];
  421.         } else { j--;}    /* stay with that space */
  422.     }
  423.     /* copy the not extended partitions back after the extended partitions */
  424.      for (i=0; i < 2; i++, j++)    {
  425.         if (rpart[i].p_flg & P_EXISTS)    {
  426.             pinfo[j].p_flg = P_EXISTS;
  427.             pinfo[j].p_st = rpart[i].p_st;
  428.             pinfo[j].p_siz = rpart[i].p_siz;
  429.             for (k = 0; k < 3; k++)
  430.                 pinfo[j].p_id[k] = rpart[i].p_id[k];
  431.         } else {j--;}
  432.     }
  433.     for (i = j; i < npart; i++)    { /* set the rest to 0 */
  434.         pinfo[i].p_flg = 0L;
  435.         pinfo[i].p_st = 0L;
  436.         pinfo[i].p_siz = 0L;
  437.         for (k = 0; k < 3; k++)
  438.             pinfo[i].p_id[k] = '0';
  439.     }
  440. }
  441.  
  442.  
  443. /* 
  444.  * check to find out the exist of device
  445.  */
  446.  
  447. rangelog(dev)
  448.  
  449. int dev;
  450.  
  451. {
  452.     PUNINFO *divinfo;
  453.     int devnum;
  454.  
  455.     ostack = Super(NULL);
  456.     divinfo = ((PUNINFO *) *((long *)(0x516)));
  457.     for (devnum = 0; devnum < MAXUNITS; ++devnum)    {
  458.         if ((int)(divinfo->pun[devnum] & 0x07) == dev)    {
  459.             delay();
  460.             nlogdevs++;
  461.         }
  462.     }
  463.     Super(ostack);
  464. }
  465.  
  466. /*
  467.  * From a PHYSICAL device unit (0->7)
  468.  * and a partition number (0->3), figure
  469.  * out the LOGICAL disk number ('C'->'P').
  470.  *
  471.  * return the LOGICAL disk number or
  472.  * ERROR if the PHYSICAL device doesn't exist.
  473.  *
  474.  */
  475. phys2log(pdev, pno)
  476. int  pdev;    /* physical device unit */
  477. int  pno;    /* partition number (0 -> 3) */
  478. {
  479.     int logdev;        /* index to step through partitions of a phys unit */
  480.  
  481.     for (logdev = 0; logdev < EXTRALOGD; logdev++) {
  482.         if (logmap[logdev].lm_physdev == pdev &&
  483.             logmap[logdev].lm_partno == pno)
  484.             return ('C'+logdev);
  485.     }
  486.     return ERROR;
  487. }
  488.  
  489.  
  490. /*
  491.  * Map block on logical device to
  492.  * block on physical device;
  493.  * return ERROR if the logical device
  494.  * doesn't exist.
  495.  */
  496. log2phys(adev, ablk)
  497. int *adev;
  498. SECTOR *ablk;
  499. {
  500.     int dev;
  501.     char xbuf[256];
  502.     
  503.     dev = *adev;
  504.     if (dev >= 0 && dev <= 17)
  505.     return OK;
  506.  
  507.     dev = toupper(dev);
  508.     if (dev >= 'C' && dev <= 
  509.                 ('C'+EXTRALOGD)) /* from C to 't' are 50 logic device */
  510.     {
  511.     dev -= 'C';
  512.     *adev = logmap[dev].lm_physdev;
  513.     *ablk = logmap[dev].lm_start + *ablk;
  514.     return OK;
  515.     }
  516.  
  517.     return ERROR;
  518. }
  519.  
  520.  
  521.  
  522. /*
  523.  * Return physical starting block# of a partition
  524.  *
  525.  */
  526. SECTOR 
  527. logstart(ldev)
  528. int ldev;    /* logical device */
  529. {
  530.     ldev = toupper(ldev);
  531.     if (ldev >= 'C' && ldev <= 
  532.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  533.         ldev -= 'C';
  534.         return (logmap[ldev].lm_start);
  535.     }
  536.     return ERROR;
  537. }
  538.  
  539.  
  540.  
  541. /*
  542.  * Return physical starting block# of a partition's data block.
  543.  *
  544.  */
  545. SECTOR 
  546. logend(ldev)
  547. int ldev;    /* logical device */
  548. {
  549.     ldev = toupper(ldev);
  550.     if (ldev >= 'C' && ldev <= 
  551.                 ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
  552.         ldev -= 'C';
  553.         return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
  554.     }
  555.     return ERROR;
  556. }
  557.  
  558.  
  559. #define    MFM 17        /* sectors per track for MFM */
  560. #define    RLL 26        /* sectors per track for RLL */
  561.  
  562.  
  563. /*
  564.  * Check if dev's root block is intact.
  565.  * Return number of sectors per track on disk.
  566.  *
  567.  */
  568. chkroot(dev, bs)
  569. int dev;
  570. char *bs;
  571. {
  572.     extern long get3bytes();
  573.     extern long get4bytes();
  574.     SETMODE *mb;
  575.     int i, ret, set, scsidrv, mask=0x0001;
  576.     int page=4, bsiz;
  577.     int head, spt;
  578.     SECTOR size, msiz, cyl;    /* size of media */
  579.     char buf[512], sendata[32];
  580.     long dmaptr, tmpptr;
  581.     char *dmahigh=0xffff8609,
  582.          *dmamid=0xffff860b,
  583.          *dmalow=0xffff860d;
  584.     
  585.     size = ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz;
  586.     
  587.     ret = OK;
  588.     if (dev == 16)    {        /* it is a IDE-AT drive */
  589.         msiz = (SECTOR)athead * (SECTOR)atcyl * (SECTOR)atspt;
  590.         if (size != msiz)
  591.             ret = ERROR;
  592.         return(ret);
  593.     } else if (dev > 7)    {    /* it is a scsi drive */
  594.         ostack = Super(NULL);
  595.         delay();
  596.         if ((ret = readcap(dev, 0, (long)0, sendata)) == OK) {
  597.             if (msiz = get4bytes(sendata))    {
  598.                 msiz += 1;
  599.                 delay();
  600.                 Super(ostack);
  601.                 goto chkend;
  602.             } 
  603.         } 
  604.         for (i = 0; i < 32; i++)
  605.             sendata[i] = 0;
  606.         if ((ret = mdsense(dev, 4, 0, 32, sendata)) == OK)    {
  607.             if((msiz=get3bytes(sendata+5)))    {
  608.                         delay();
  609.                         Super(ostack);
  610.                         goto chkend;
  611.             }
  612.         }
  613.         for (i = 0; i < 32; i++)
  614.             sendata[i] = 0;
  615.         if ((ret = mdsense(dev, 0, 0, 16, sendata)) == OK)    {
  616.             if((msiz=get3bytes(sendata+5)))    {
  617.                         delay();
  618.                         Super(ostack);
  619.                         goto chkend;
  620.             }
  621.         }
  622.         for (i = 0; i < 32; i++)
  623.             sendata[i] = 0;
  624.         if ((ret = mdsense(dev, 3, 0, 32, sendata)) == OK)    {
  625.             if((msiz=get3bytes(sendata+5)))    {
  626.                         delay();
  627.                         Super(ostack);
  628.                         goto chkend;
  629.             }
  630.         }
  631.         msiz = size;
  632.         delay();
  633.         Super(ostack);
  634.         goto chkerr;
  635.     }
  636.  
  637.     ostack = Super(NULL);
  638.     /* Get format parameters/ disk size from media */
  639.     set = typedev & (mask << dev);
  640.     scsidrv = typedrv & (mask << dev);
  641.     bsiz = ((set) || (scsidrv)) ? (16) : (22);
  642.     if ((set) || (scsidrv))    {
  643.         for (i = 0; i < 32; i++)
  644.             sendata[i] = 0;
  645.         mdsense(dev, 0, 0, bsiz, sendata);
  646.         if((msiz=get3bytes(sendata+5)))    {
  647.                     delay();
  648.                     Super(ostack);
  649.                     goto chkend;
  650.         }
  651. redopg:
  652.         for (i = 0; i < 32; i++)
  653.             sendata[i] = 0;
  654.         ret = mdsense(dev, page, 0, 32, sendata);/* use page code 4, but get */
  655.                                             /* info from the mdsense header */
  656.         for (i = 0; i < 32; i++)
  657.             if (sendata[i])
  658.                 break;
  659.         if ((i==32) && (page == 4))        {
  660.             page = 3;
  661.             goto redopg;
  662.         } else if (i == 32)    {
  663.             msiz = size;
  664.             delay();
  665.             Super(ostack);
  666.             goto chkend;
  667.         }
  668.         if (!(msiz = get3bytes(sendata+5)))    {
  669.             if (page == 4)    {
  670.                 page = 3;
  671.                 /*
  672.                 cyl = get3bytes(sendata+14);
  673.                 head = *(sendata+17);
  674.                 */
  675.                 goto redopg;
  676.             } else {
  677.                 /*
  678.                 spt = getword(sendata+22);
  679.                 msiz = cyl * head * spt;
  680.                 */
  681.                 msiz = size;
  682.             }
  683.         }
  684.         delay();
  685.         Super(ostack);
  686.         goto chkend;
  687.     } else    {
  688.         ret = mdsense(dev, 0, 0, 22, sendata);
  689.         delay();
  690.         Super(ostack);
  691.  
  692.         /* If full SCSI, will return number of blocks */
  693.         /* on disk at byte 5, 6 and 7.  If Adaptec,   */
  694.         /* will return 0 for number of blocks on disk */
  695.         /* on SCSI. */
  696.  
  697.             if (!(msiz = get3bytes(sendata+5))) {    /* no disk size returned? */
  698.             /* Yup, ie., it's adaptec's.  Interpret as SETMODE structure */
  699.             mb = (SETMODE *)sendata;
  700.             /* get number of cylinders */
  701.             cyl = mb->smd_cc[0];
  702.             cyl <<= 8;
  703.             cyl |= mb->smd_cc[1];
  704.     
  705.             /* get number of heads */
  706.             head = mb->smd_dhc;
  707.     
  708.             msiz = (SECTOR)head * (SECTOR)cyl * MFM;
  709.     
  710.             for (i = 0; i < 20; i++) {
  711.                 if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
  712.                     /* find out whether data has been transferred, by
  713.                           checking if dma pointer has been moved.      */
  714.  
  715.                     ostack = Super(NULL);
  716.                     delay();
  717.                     dmaptr = *dmahigh;
  718.                     dmaptr &= 0x0000003f;
  719.                     dmaptr <<= 16;
  720.                     tmpptr = *dmamid;
  721.                     tmpptr &= 0x000000ff;
  722.                     tmpptr <<= 8;
  723.                     dmaptr |= tmpptr;
  724.                     tmpptr = *dmalow;
  725.                     tmpptr &= 0x000000ff;
  726.                     dmaptr |= tmpptr;
  727.                     delay();
  728.                     Super(ostack);
  729.  
  730.                     if (dmaptr != buf)
  731.                         break;
  732.                    } else {            /* rdsects return an error */
  733.                     if (tsterr(ret) == OK) {
  734.                            break;
  735.                     }
  736.                 }
  737.             }
  738.     
  739.             if (ret == MDMCHGD)        /* check if error occurred */
  740.                 return (ret);
  741.        
  742.             /* Determine if media is MFM or RLL */
  743.             if (i < 20)    {
  744.                 msiz = (SECTOR)head * (SECTOR)cyl * RLL;
  745.             }
  746.             goto chkend;
  747.         }
  748.     }
  749. chkerr:
  750.     if (ret != 0) {
  751.         ret = errcode(dev);
  752.         if (tsterr(ret) != OK) 
  753.             return ERROR;
  754.         return (-3);    /* don't have to show the alert box */
  755.     }
  756. chkend:
  757.     if (size != msiz)
  758.         ret = ERROR;
  759.     else 
  760.         ret = OK;
  761.         
  762.     return (ret);
  763. }
  764.  
  765. /*
  766.  * Chkparm()
  767.  *    Check if given logical device has the asssumed parameters.
  768.  * Assumptions are:
  769.  *    - 512 bytes/sector
  770.  *    - 2 sectors/cluster
  771.  *    - 1 reserved sector
  772.  *    - 2 FATs
  773.  *
  774.  * Input:
  775.  *    ldev - logical device number ('C' -> 'P').
  776.  *
  777.  * Return:
  778.  *    OK - parameters of partition match the assumptions
  779.  *    ERROR - something went wrong.
  780.  *
  781.  * Comment:
  782.  *    Number of FATs is assumed to be 2.  Cannot check this 
  783.  * because previous version of HDX did not put that in the boot
  784.  * sector.
  785.  */
  786. chkparm(ldev)
  787. int ldev;
  788. {
  789.     char bs[512];        /* boot sector */
  790.     BOOT *boot;            /* boot structure */
  791.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  792.     int ret;
  793.  
  794.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  795.         if (tsterr(ret) != OK)
  796.             err(bootread);
  797.         ret = ERROR;
  798.         goto parmend;
  799.     }    
  800.  
  801.     boot = (BOOT *)bs;
  802.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  803.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  804.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  805.     if (bps % BPS            /* bytes per sector == ratio of 512 ? */
  806.     || res != 1) {            /* num sectors reserved == 1 ? */
  807.     ret = ERROR;            /* Nope, different from assumptions */
  808.     goto parmend;
  809.     }
  810.     
  811.     /* Check if sectors per cluster make sense */
  812.     if (boot->b_spc != 2) {
  813.         ret = ERROR;
  814.         goto parmend;
  815.     }
  816.     
  817.     ret = OK;                /* If yes, return OK */
  818.  
  819. parmend:
  820.     return ret;
  821. }
  822.  
  823.  
  824. ichkparm(ldev)
  825. int ldev;
  826. {
  827.     char bs[512];        /* boot sector */
  828.     BOOT *boot;            /* boot structure */
  829.     UWORD bps, res, siz;    /* bytes/sector, num reserved sectors, ldev size */
  830.     int ret;
  831.  
  832.     if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
  833.         if (tsterr(ret) != OK)
  834.             err(bootread);
  835.         ret = ERROR;
  836.         goto parmend;
  837.     }    
  838.  
  839.     boot = (BOOT *)bs;
  840.     gw((UWORD *)&boot->b_bps, &bps);    /* what is number bytes/sector? */
  841.     gw((UWORD *)&boot->b_res, &res);    /* what is num of reserved sectors? */
  842.     gw((UWORD *)&boot->b_nsects, &siz);    /* what is size of partition */
  843.     if (bps != 512            /* bytes per sector == 512 ? */
  844.     || res != 1) {            /* num sectors reserved == 1 ? */
  845.     ret = ERROR;            /* Nope, different from assumptions */
  846.     goto parmend;
  847.     }
  848.     
  849.     /* Check if sectors per cluster make sense */
  850.     if ((siz >= 0x8000L && boot->b_spc != 4) ||
  851.         (siz < 0x8000L && boot->b_spc != 2)) {
  852.         ret = ERROR;
  853.         goto parmend;
  854.     }
  855.     
  856.     ret = OK;                /* If yes, return OK */
  857.  
  858. parmend:
  859.     return ret;
  860. }
  861.  
  862.  
  863. /*
  864.  * Get dev's root block.
  865.  *
  866.  */
  867. getroot(dev, buf, sect)
  868. int dev;
  869. char *buf;
  870. SECTOR sect;
  871. {
  872.     return rdsects(dev, 1, buf, sect);
  873. }
  874.  
  875.  
  876. /*
  877.  * Put dev's root block.
  878.  *
  879.  */
  880. putroot(dev, buf, sect)
  881. int dev;
  882. char *buf;
  883. SECTOR sect;
  884. {
  885.     return wrsects(dev, 1, buf, sect);
  886. }
  887.  
  888.  
  889. /*
  890.  *  Read sector(s) from dev.
  891.  *
  892.  *  Input:
  893.  *    dev - device number (logical or physical).
  894.  *    num - number of sectors to read.
  895.  *    buf - buffer to write data read.
  896.  *    sect - starting sector number to read from.
  897.  *
  898.  *  Return:
  899.  *    errnum - 0: if read is successful.
  900.  *         an error code: if read is unsuccessful.
  901.  */
  902. rdsects(dev, num, buf, sect)
  903. int dev;            /* device number (logical or physical) */
  904. UWORD num;            /* number of sectors to read */
  905. char *buf;
  906. SECTOR sect;            /* starting sector to read from */
  907. {
  908.     int errnum;
  909.  
  910.     if (log2phys(&dev, §) < 0)
  911.     return ERROR;
  912.  
  913.     ostack = Super(NULL);
  914.     if (dev == 16)    { /* it is a AT drive */
  915.         /*
  916.         if (!(athead*atspt*sect))    {
  917.             formaterr(dev);
  918.             errnum = ERROR;
  919.         } else {
  920.             errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  921.         }
  922.         */
  923.         errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
  924.     } else {
  925.         /*
  926.         if (spscsixst)    {
  927.             resetspscsi();
  928.         }
  929.         */
  930.         errnum = hread(sect, num, buf, (UWORD)dev);
  931.     }
  932.     /*
  933.     if (errnum == 04)    {      the drive is stop 
  934.         delay();
  935.         stunt();
  936.         delay();
  937.         errnum = hread(sect, num, buf, (UWORD)dev);
  938.     }
  939.     */
  940.     delay();
  941.     Super(ostack);
  942.  
  943.     if (errnum > 0) {
  944.         errnum = errcode(dev);
  945.     }
  946.         
  947.     return errnum;        /* return the error code */
  948. }
  949.  
  950.  
  951. /*
  952.  *  Write sector(s) to dev.
  953.  *
  954.  *  Input:
  955.  *    dev - device number (logical or physical).
  956.  *    num - number of sectors to write.
  957.  *    buf - buffer with data to be written.
  958.  *    sect - starting sector number to write to.
  959.  *
  960.  *  Return:
  961.  *    errnum - 0: if write is successful.
  962.  *         an error code: if write is unsuccessful.
  963.  */
  964. wrsects(dev, num, buf, sect)
  965. int dev;            /* device number (logical or physical */
  966. UWORD num;            /* number of sectors to write */
  967. char *buf;            /* buffer with data to be written */
  968. SECTOR sect;            /* starting sector to write to */
  969. {
  970.     int errnum;
  971.  
  972.     if (log2phys(&dev, §) < 0)
  973.     return ERROR;
  974.  
  975.     ostack = Super(NULL);
  976.     if (dev == 16)    { /* it is a AT drive */
  977.         /*
  978.         if (!(athead*atspt*sect))    {
  979.             formaterr(dev);
  980.             errnum = ERROR;
  981.         } else {
  982.             errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  983.         }
  984.         */
  985.         errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
  986.     } else {
  987.         errnum = hwrite(sect, num, buf, (UWORD)dev);
  988.     }
  989.     delay();
  990.     Super(ostack);
  991.  
  992.     if (errnum > 0) {
  993.         errnum = errcode(dev);
  994.     }
  995.     return errnum;
  996. }
  997.  
  998.  
  999. /*
  1000.  * Zero range of sectors on dev.
  1001.  *
  1002.  */
  1003. zerosect(dev, start, count)
  1004. int dev;
  1005. SECTOR start;
  1006. UWORD count;
  1007. {
  1008.     char *zbuf;
  1009.     int  v;
  1010.     UWORD i;
  1011.  
  1012.     if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
  1013.         return err(nomemory);
  1014.         
  1015.     if (log2phys(&dev, &start) < 0) {
  1016.         free(zbuf);
  1017.     return ERROR;
  1018.     }
  1019.  
  1020.     fillbuf(zbuf, (long)ZBUFSIZ, 0L);
  1021.  
  1022.     while (count)
  1023.     {
  1024.         if (count > ZCOUNT)
  1025.             i = ZCOUNT;
  1026.         else i = count;
  1027.  
  1028.     if ((v = wrsects(dev, i, zbuf, start)) != 0)
  1029.         break;
  1030.     start += i;
  1031.     count -= i;
  1032.     }
  1033.     free(zbuf);
  1034.     
  1035.     return v;
  1036. }
  1037.